package com.wchc.order.service;

import com.alibaba.fastjson.JSON;
import com.wchc.config.redis.RedisService;
import com.wchc.order.Order;
import com.wchc.order.OrderActionState;
import com.wchc.order.OrderState;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.redis.RedisStateMachinePersister;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.concurrent.ThreadLocalRandom;

@Service
public class OrderService {

    @Resource
    private RedisService redisService;

    @Resource
    private StateMachine<OrderState, OrderActionState> orderStateMachine;

    @Resource
    private RedisStateMachinePersister<OrderState, OrderActionState> stateMachineRedisPersister;


    public Order createOrder(String productId) {

        Order order = new Order();
        order.setOrderId(new Date().getTime() +"");
        order.setProductId(productId);
        order.setOrderState(OrderState.ORDER_WAIT_PAY);
        double v = ThreadLocalRandom.current().nextDouble(100);
        order.setPrice(v);

        redisService.set(order.getOrderId(), JSON.toJSONString(order));
        return order;
    }

    public Order payOrder(String orderId) {

        String s = redisService.get(orderId);
        Order order = JSON.parseObject(s, Order.class);
        Message<OrderActionState> message = MessageBuilder.withPayload(OrderActionState.PAY)
                .setHeader("order", order).build();
        if(changeStateAction(message,order)) return order;
        return null;
    }



    public Order sendOrder(String orderId) {
        String s = redisService.get(orderId);
        Order order = JSON.parseObject(s, Order.class);
        Message<OrderActionState> message = MessageBuilder.withPayload(OrderActionState.SEND)
                .setHeader("order", order).build();
        if(changeStateAction(message,order)) return order;
        return null;
    }

    public Order receiveOrder(String orderId) {
        String s = redisService.get(orderId);
        Order order = JSON.parseObject(s, Order.class);
        Message<OrderActionState> message = MessageBuilder.withPayload(OrderActionState.RECEIVE)
                .setHeader("order", order).build();
        if(changeStateAction(message,order)) return order;
        return null;
    }


    private boolean changeStateAction(Message<OrderActionState> message, Order order){

        try {
            orderStateMachine.start();
            stateMachineRedisPersister.restore(orderStateMachine,order.getOrderId()+"STATE");
            boolean resp = orderStateMachine.sendEvent(message);
            stateMachineRedisPersister.persist(orderStateMachine,order.getOrderId()+"STATE");
            return resp;
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            orderStateMachine.stop();
        }
        return false;
    }
}
